package com.panfeng.xcloud.boss.provider.assets.service.impl;

import com.panfeng.xcloud.boss.provider.assets.dao.mapper.UserBaseMapperExt;
import com.panfeng.xcloud.boss.provider.assets.dao.mapper.UserWalletInfoMapperExt;
import com.panfeng.xcloud.boss.provider.assets.dao.mapper.WalletAssetsFlowMapperExt;
import com.panfeng.xcloud.boss.provider.assets.dao.mapper.WithdrawLogMapperExt;
import com.panfeng.xcloud.boss.provider.assets.dto.BackTeamBonusPoolFlowDTO;
import com.panfeng.xcloud.boss.provider.assets.dto.WalletAssetsFlowExtendItemDTO;
import com.panfeng.xcloud.boss.provider.assets.dto.request.BuyActiveCodeReqDTO;
import com.panfeng.xcloud.boss.provider.assets.dto.request.BuyPointCardReqDTO;
import com.panfeng.xcloud.boss.provider.assets.dto.request.TransferReqDTO;
import com.panfeng.xcloud.boss.provider.assets.dto.request.WithdrawReqDTO;
import com.panfeng.xcloud.boss.provider.assets.dto.response.*;
import com.panfeng.xcloud.boss.provider.assets.service.IUserWalletService;
import com.panfeng.xcloud.boss.provider.assets.utils.OrderNoGenerate;
import com.panfeng.xcloud.common.core.configuration.DataDictionaryConfig;
import com.panfeng.xcloud.common.core.enums.*;
import com.panfeng.xcloud.common.core.exceptions.BaseBizException;
import com.panfeng.xcloud.common.core.utils.ConvertUtils;
import com.panfeng.xcloud.common.core.utils.MD5Utils;
import com.panfeng.xcloud.common.core.utils.StringUtils;
import com.panfeng.xcloud.dao.assets.entity.UserWalletInfo;
import com.panfeng.xcloud.dao.assets.entity.WalletAssetsFlow;
import com.panfeng.xcloud.dao.assets.entity.WithdrawLog;
import com.panfeng.xcloud.dao.base.MapperSupport;
import com.panfeng.xcloud.dao.member.entity.UserBase;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class UserWalletServiceImpl extends MapperSupport<Integer, WalletAssetsFlow, WalletAssetsFlowMapperExt> implements IUserWalletService {

    @Autowired
    private WithdrawLogMapperExt withdrawLogMapperExt;

    @Autowired
    private UserWalletInfoMapperExt userWalletInfoMapperExt;

    @Autowired
    private UserBaseMapperExt userBaseMapperExt;

    @Autowired
    private WalletAssetsFlowMapperExt walletAssetsFlowMapperExt;

    @Autowired
    private DataDictionaryConfig dataDictionaryConfig;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WithdrawRespDTO withdraw(WithdrawReqDTO withdrawReqDTO) {
        //校验交易密码
        checkTransPwd(withdrawReqDTO.getUserId(), withdrawReqDTO.getTransPwd());

        //先校验可用余额是否足够
        UserWalletInfo req = new UserWalletInfo();
        req.setUserId(withdrawReqDTO.getUserId());
        req.setChainName(withdrawReqDTO.getChainName());
        req.setCoinName(withdrawReqDTO.getCoinName());
        req.setAddress(withdrawReqDTO.getFromAddress());
        BigDecimal avaliableBalance = userWalletInfoMapperExt.selectOne(req).getAvaliableBalance();

        //查询手续费
        BigDecimal fee = new BigDecimal(dataDictionaryConfig.getCodeToNameMap().get(DataDictionaryTypeEnum.tx_fee.getCode()));

        avaliableBalance = avaliableBalance.subtract(fee);

        if (avaliableBalance.compareTo(withdrawReqDTO.getFinalAmount()) < 0) {
            throw new BaseBizException(ResponseStatusEnum.ACCOUNT_QUOTA_ERROR);
        }

        //更新用户资产
        UserWalletInfo req1 = new UserWalletInfo();
        req1.setUserId(withdrawReqDTO.getUserId());
        req1.setChainName(withdrawReqDTO.getChainName());
        req1.setCoinName(withdrawReqDTO.getCoinName());
        req1.setAddress(withdrawReqDTO.getFromAddress());
        req1.setAvaliableBalance((withdrawReqDTO.getFinalAmount().add(fee)).negate());
        req1.setFrozenBalance(withdrawReqDTO.getFinalAmount().add(fee));
        int i = userWalletInfoMapperExt.updateUserWalletInfo(req1);

        if (i <= 0) {
            throw new BaseBizException(ResponseStatusEnum.WITHDRAW_CURRENCY_ERROR);
        }

        //往withdraw_log表中插入数据
        WithdrawLog withdrawLog = new WithdrawLog();

        withdrawLog.setUserId(withdrawReqDTO.getUserId());
        withdrawLog.setFlowOrderId(OrderNoGenerate.getOrderIdByTime());
        withdrawLog.setTargetAddress(withdrawReqDTO.getTargetAddress());
        withdrawLog.setFromAddress(withdrawReqDTO.getFromAddress());
        withdrawLog.setFinalAmount(withdrawReqDTO.getFinalAmount());
        withdrawLog.setCoinName(withdrawReqDTO.getCoinName());
        withdrawLog.setChainName(withdrawReqDTO.getChainName());
        withdrawLog.setState(WithdrawLogTypeEnum.WAIT_AUDIT.getCode());
        withdrawLog.setTxFee(fee);
        withdrawLog.setCreateTime(new Date());
        withdrawLog.setModifyTime(new Date());
        withdrawLog.setNote(withdrawReqDTO.getNote());
        int i1 = withdrawLogMapperExt.insertSelective(withdrawLog);

        if (i1 <= 0) {
            throw new BaseBizException(ResponseStatusEnum.WITHDRAW_CURRENCY_ERROR);
        }

        insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(),
                withdrawReqDTO.getUserId(), null, null, null, new Date(), withdrawReqDTO.getCoinName(),
                withdrawReqDTO.getFinalAmount(), WalletAssetsFlowTypeEnum.WITHDRAWAUDIT.getCode(), null, null);

        WithdrawRespDTO withdrawRespDTO = ConvertUtils.convert(withdrawLog, WithdrawRespDTO.class);
        return withdrawRespDTO;
    }

    /**
     * 用户互转
     *
     * @param transferReqDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TransferRespDTO transfer(TransferReqDTO transferReqDTO) {
        //校验交易密码
        checkTransPwd(transferReqDTO.getUserId(), transferReqDTO.getTransPwd());

        //第一步,判断转账目的账号是否存在
        UserBase toUserBase = userBaseMapperExt.selectAccountExist(transferReqDTO.getToAccount());

        if (toUserBase == null) {
            log.error(">>> 转帐目地账号:{} 不存在 <<<", transferReqDTO.getToAccount());
            throw new BaseBizException(ResponseStatusEnum.USER_NOT_EXIST);
        }

        UserWalletInfo temp = new UserWalletInfo();
        temp.setUserId(toUserBase.getUserId());
        temp.setChainName(transferReqDTO.getChain());
        temp.setCoinName(transferReqDTO.getCoin());
        UserWalletInfo toUserWalletInfo = userWalletInfoMapperExt.selectOne(temp);

        //第二步,判断该币种可用余额是否足够
        UserWalletInfo reqUserWalletInfo = new UserWalletInfo();
        reqUserWalletInfo.setUserId(transferReqDTO.getUserId());
        reqUserWalletInfo.setChainName(transferReqDTO.getChain());
        reqUserWalletInfo.setCoinName(transferReqDTO.getCoin());
        UserWalletInfo userWalletInfo = userWalletInfoMapperExt.selectOne(reqUserWalletInfo);

        //查询手续费
        BigDecimal fee = new BigDecimal(dataDictionaryConfig.getCodeToNameMap().get(DataDictionaryTypeEnum.tx_fee.getCode()));

        if ((userWalletInfo.getAvaliableBalance().subtract(fee)).compareTo(transferReqDTO.getAmount()) < 0) {
            log.error(">>> 用户id:{} 公链:{} 币名:{}  钱包余额不足 <<<", transferReqDTO.getUserId(), transferReqDTO.getChain(), transferReqDTO.getCoin());
            throw new BaseBizException(ResponseStatusEnum.WALLET_BALANCE_NOT_ENOUGH);
        }

        //第三步,往wallet_assets_flow表插入转账数据
        String flowOrderId = OrderNoGenerate.getOrderIdByTime();
        int i = insertWalletAssetsFlow(flowOrderId, userWalletInfo.getUserId(),
                userWalletInfo.getAddress(), toUserBase.getUserId(), toUserWalletInfo.getAddress(), new Date(), transferReqDTO.getCoin(),
                transferReqDTO.getAmount(), WalletAssetsFlowTypeEnum.TRANSFER.getCode(), null, transferReqDTO.getNote());
        if (i <= 0) {
            log.error(">>> 用户id:{} 互转失败 <<<", transferReqDTO.getUserId());
            throw new BaseBizException(ResponseStatusEnum.INSERT_WALLET_ASSETS_FLOW_ERROR);
        }

        //第四步,更新user_wallet_info表双方的可用余额
        UserWalletInfo req1 = new UserWalletInfo();
        req1.setUserId(transferReqDTO.getUserId());
        req1.setChainName(transferReqDTO.getChain());
        req1.setCoinName(transferReqDTO.getCoin());
        req1.setAddress(userWalletInfo.getAddress());
        req1.setAvaliableBalance((transferReqDTO.getAmount().add(fee)).negate());
        int i1 = userWalletInfoMapperExt.updateUserWalletInfo(req1);
        if (i1 <= 0) {
            log.error(">>> 用户id:{} 更新余额失败 <<<", transferReqDTO.getUserId());
            throw new BaseBizException(ResponseStatusEnum.TRADE_UPDATE_USDT_BALANCE_ERROR);
        }

        UserWalletInfo req2 = new UserWalletInfo();
        req2.setUserId(toUserWalletInfo.getUserId());
        req2.setChainName(transferReqDTO.getChain());
        req2.setCoinName(transferReqDTO.getCoin());
        req2.setAddress(toUserWalletInfo.getAddress());
        req2.setAvaliableBalance(transferReqDTO.getAmount());
        int i2 = userWalletInfoMapperExt.updateUserWalletInfo(req2);
        if (i2 <= 0) {
            log.error(">>> 用户id:{} 更新余额失败 <<<", toUserWalletInfo.getUserId());
            throw new BaseBizException(ResponseStatusEnum.TRADE_UPDATE_USDT_BALANCE_ERROR);
        }

        TransferRespDTO transferRespDTO = new TransferRespDTO();
        transferRespDTO.setFlowOrderId(flowOrderId);
        transferRespDTO.setUserId(userWalletInfo.getUserId());
        transferRespDTO.setFromAddress(userWalletInfo.getAddress());
        transferRespDTO.setToUserId(toUserBase.getUserId());
        transferRespDTO.setToAddress(toUserWalletInfo.getAddress());
        transferRespDTO.setCoin(transferReqDTO.getCoin());
        transferRespDTO.setAmount(transferReqDTO.getAmount());
        transferRespDTO.setType(WalletAssetsFlowTypeEnum.TRANSFER.getCode());
        transferRespDTO.setNote(transferReqDTO.getNote());
        return transferRespDTO;
    }

    /**
     * 购买点卡
     *
     * @param buyPointCardReqDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public BuyPointCardRespDTO buyPointCard(BuyPointCardReqDTO buyPointCardReqDTO) {
        //校验交易密码
        checkTransPwd(buyPointCardReqDTO.getUserId(), buyPointCardReqDTO.getTransPwd());

        //第一步,判断可用余额是否足够
        UserWalletInfo req = new UserWalletInfo();
        req.setChainName(ChainTypeEnum.TRON.getCode());
        req.setCoinName(CoinTypeEnum.USDT.getCode());
        req.setUserId(buyPointCardReqDTO.getUserId());
        UserWalletInfo userWalletInfo = userWalletInfoMapperExt.selectOne(req);

        if (userWalletInfo.getAvaliableBalance().compareTo(buyPointCardReqDTO.getAmount()) < 0) {
            log.error(">>> 用户id:{} 购买点卡可用余额不足 <<<", buyPointCardReqDTO.getUserId());
            throw new BaseBizException(ResponseStatusEnum.WALLET_BALANCE_NOT_ENOUGH);
        }

        //第二步,获取点卡兑换汇率
        BigDecimal pointCardRatio = new BigDecimal(dataDictionaryConfig.getCodeToNameMap().get(DataDictionaryTypeEnum.point_card_ratio.getCode()));

        //第三步,往wallet_assets_flow插入数据
        String flowOrderId = OrderNoGenerate.getOrderIdByTime();
        int i = insertWalletAssetsFlow(flowOrderId, buyPointCardReqDTO.getUserId(),
                null, null, null, new Date(), userWalletInfo.getCoinName(),
                buyPointCardReqDTO.getAmount(), WalletAssetsFlowTypeEnum.BUYPOINTCARD.getCode(), null, buyPointCardReqDTO.getNote());
        if (i <= 0) {
            log.error(">>> 用户id:{} 插入数据失败 <<<", buyPointCardReqDTO.getUserId());
            throw new BaseBizException(ResponseStatusEnum.TRADE_UPDATE_USDT_BALANCE_ERROR);
        }

        //第四步,更新user_wallet_info数据，扣除可用余额，增加点卡余额
        UserWalletInfo req1 = new UserWalletInfo();
        req1.setUserId(userWalletInfo.getUserId());
        req1.setChainName(ChainTypeEnum.TRON.getCode());
        req1.setCoinName(CoinTypeEnum.USDT.getCode());
        req1.setAddress(userWalletInfo.getAddress());
        req1.setAvaliableBalance(buyPointCardReqDTO.getAmount().negate());
        req1.setPointBalance(buyPointCardReqDTO.getAmount().multiply(pointCardRatio));
        int i1 = userWalletInfoMapperExt.updateUserWalletInfo(req1);

        if (i1 <= 0) {
            log.error(">>> 用户id:{} 更新余额失败 <<<", userWalletInfo.getUserId());
            throw new BaseBizException(ResponseStatusEnum.TRADE_UPDATE_USDT_BALANCE_ERROR);
        }

        //更新用户等级
        updateUserLevel(buyPointCardReqDTO);

        //分红
        shareBonus(buyPointCardReqDTO);

        BuyPointCardRespDTO buyPointCardRespDTO = new BuyPointCardRespDTO();
        buyPointCardRespDTO.setFlowOrderId(flowOrderId);

        return buyPointCardRespDTO;
    }

    /**
     * 购买激活码
     *
     * @param buyActiveCodeReqDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public BuyActiveCodeRespDTO buyActiveCode(BuyActiveCodeReqDTO buyActiveCodeReqDTO) {
        //校验交易密码
        checkTransPwd(buyActiveCodeReqDTO.getUserId(), buyActiveCodeReqDTO.getTransPwd());

        BuyActiveCodeRespDTO buyActiveCodeRespDTO = new BuyActiveCodeRespDTO();

        //第一步,判断可用余额是否足够
        UserWalletInfo req = new UserWalletInfo();
        req.setUserId(buyActiveCodeReqDTO.getUserId());
        req.setChainName(ChainTypeEnum.TRON.getCode());
        req.setCoinName(CoinTypeEnum.USDT.getCode());
        UserWalletInfo userWalletInfo = userWalletInfoMapperExt.selectOne(req);

        BigDecimal costUsdt = new BigDecimal(dataDictionaryConfig.getCodeToNameMap().get(DataDictionaryTypeEnum.buy_active_code_price.getCode()));

        if (userWalletInfo.getAvaliableBalance().compareTo(costUsdt) < 0) {
            log.error(">>> 用户id:{} 购买激活码可用余额不足 <<<", buyActiveCodeReqDTO.getUserId());
            throw new BaseBizException(ResponseStatusEnum.WALLET_BALANCE_NOT_ENOUGH);
        }

        //第二步,往wallet_assets_flow表插入数据
        String flowOrderId = OrderNoGenerate.getOrderIdByTime();
        int i = insertWalletAssetsFlow(flowOrderId, buyActiveCodeReqDTO.getUserId(),
                userWalletInfo.getAddress(), null, null, new Date(), CoinTypeEnum.USDT.getCode(),
                costUsdt, WalletAssetsFlowTypeEnum.BUYACTIVE.getCode(), null, buyActiveCodeReqDTO.getNote());

        if (i <= 0) {
            log.error(">>> 用户id:{} 更新余额失败 <<<", userWalletInfo.getUserId());
            throw new BaseBizException(ResponseStatusEnum.TRADE_UPDATE_USDT_BALANCE_ERROR);
        }

        //第三步,更新user_wallet_info表的可用余额，激活状态，激活剩余有效天数
        Integer activeDays = new Integer(dataDictionaryConfig.getCodeToNameMap().get(DataDictionaryTypeEnum.active_days.getCode()));

        UserWalletInfo req1 = new UserWalletInfo();
        req1.setUserId(userWalletInfo.getUserId());
        req1.setChainName(userWalletInfo.getChainName());
        req1.setCoinName(userWalletInfo.getCoinName());
        req1.setAddress(userWalletInfo.getAddress());
        req1.setAvaliableBalance(costUsdt.negate());
        req1.setActiveStatus(1);
        req1.setActiveRestTime(activeDays);
        int i1 = userWalletInfoMapperExt.updateUserWalletInfo(req1);

        if (i1 <= 0) {
            log.error(">>> 用户id:{} 更新余额失败 <<<", userWalletInfo.getUserId());
            throw new BaseBizException(ResponseStatusEnum.TRADE_UPDATE_USDT_BALANCE_ERROR);
        }

        buyActiveCodeRespDTO.setFlowOrderId(flowOrderId);

        return buyActiveCodeRespDTO;
    }

    /**
     * 检验交易密码
     *
     * @return
     */
    public void checkTransPwd(String userId, String transPwd) {
        UserInfoAuthRespDTO userInfoAuthRespDTO = userBaseMapperExt.queryUserinfoAuth(userId);
        String newPwd = MD5Utils.digest(transPwd);
        if (!newPwd.equals(userInfoAuthRespDTO.getPwd())) {
            throw new BaseBizException(ResponseStatusEnum.TRANS_PWD_FOR_SENDXD_ERROR);
        }
    }

    private void updateUserLevel(BuyPointCardReqDTO buyPointCardReqDTO) {
        String userId = buyPointCardReqDTO.getUserId();
        BigDecimal amount = buyPointCardReqDTO.getAmount();
        // 查询用户社区上游 -->    Map(memberUserId:社区上游用户Id，memberUserLevel：社区上游用户级别)
        List<Map<String, String>> listMemberMap = userBaseMapperExt.listCommunityUpstreamUser(userId);
        if (listMemberMap.size() < 2) {
            //没有直推用户，不触发会员级别晋升
            return;
        }
        //获取有效用户需要购买点卡数量
        BigDecimal activeUserNeedAmount = new BigDecimal(userBaseMapperExt.findActiveUserNeedAmount());
        if (amount.compareTo(activeUserNeedAmount) < 0) {
            //amount小于有效用户购买点卡数量，不触发会员级别晋升
            return;
        }
        //获取直推userId,
        String userId1 = listMemberMap.get(1).get("memberUserId");
        if (Integer.valueOf(listMemberMap.get(1).get("memberUserLevel")) != 0) {
            //userId1直推会员级别不为0，不触发会员级别晋升
            return;
        }
        //查找直推活跃用户数
        Integer count = userBaseMapperExt.countActiveUserByUserId(userId1, activeUserNeedAmount);
        if (count == null || count != 10) {
            //userId1直推活跃用户数不等于10不触发会员级别晋升
            return;
        }
        //将userId1会员级别升为v1
        userBaseMapperExt.updateMemberLevel(userId1, "1");
        //查找userId1 直推 userId2,
        if (listMemberMap.size() < 3) {
            //没有上级用户，不触发会员级别晋升
            return;
        }
        String userId2 = listMemberMap.get(2).get("memberUserId");
        if (Integer.valueOf(listMemberMap.get(2).get("memberUserLevel")) != 1) {
            //userId2会员级别不为1，不触发会员级别晋升
            return;
        }
        //查找userId2直推v1级别会员个数
        count = userBaseMapperExt.countInviterMembersByUserIdAndLevel(userId2, "1");
        if (count == null || count != 3) {
            //userId2直推v1级别会员的个数不等于3，不触发晋升
            return;
        }
        //userId2升为v2
        userBaseMapperExt.updateMemberLevel(userId2, "2");
        //查找userId2 直推 userId3,
        String userId3 = listMemberMap.get(3).get("memberUserId");
        if (Integer.valueOf(listMemberMap.get(3).get("memberUserLevel")) != 2) {
            //userId3会员级别不为2，不触发晋升
            return;
        }
        //查找userId3直推v2级别会员个数
        count = userBaseMapperExt.countInviterMembersByUserIdAndLevel(userId3, "2");
        if (count == null || count == 3) {
            //userId3直推v2级别会员个数为3，触发晋升,userId3 升为v3
            userBaseMapperExt.updateMemberLevel(userId, "3");
        }
    }

    private void shareBonus(BuyPointCardReqDTO buyPointCardReqDTO) {
        // 查询用户社区上游 -->    Map(memberUserId:社区上游用户Id，memberUserLevel：社区上游用户级别)
        List<Map<String, String>> listMemberMap = userBaseMapperExt.listCommunityUpstreamUser(buyPointCardReqDTO.getUserId());
        String userName = userBaseMapperExt.selectOne(buyPointCardReqDTO.getUserId()).getNickname();
        String note = "来自社区成员" + userName + "推荐奖";
        //临时变量
        BigDecimal temAmount = new BigDecimal(0);
        BigDecimal amount = buyPointCardReqDTO.getAmount();
        //盈余 (分红过后剩余)
        BigDecimal surplus = amount;
        List<WalletAssetsFlowExtendItemDTO> walletAssetsFlowS = new ArrayList<>();
        WalletAssetsFlowExtendItemDTO walletAssetsFlow = null;
        //直推用户
        if (listMemberMap.size() >= 2) {
            temAmount = amount.multiply(new BigDecimal(0.2));
            userBaseMapperExt.systemRechargeAddUserWalletInfo(listMemberMap.get(1).get("memberUserId"), CoinTypeEnum.USDT.getCode(), temAmount);
            insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(),
                    null, listMemberMap.get(1).get("memberUserId"), null, new Date(), CoinTypeEnum.USDT.getCode(),
                    temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note + "(直推)!");
            surplus = surplus.subtract(temAmount);
        }
        //间推用户
        if (listMemberMap.size() >= 3) {
            temAmount = amount.multiply(new BigDecimal(0.1));
            userBaseMapperExt.systemRechargeAddUserWalletInfo(listMemberMap.get(2).get("memberUserId"), CoinTypeEnum.USDT.getCode(), temAmount);
            insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(),
                    null, listMemberMap.get(2).get("memberUserId"), null, new Date(), CoinTypeEnum.USDT.getCode(),
                    temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note + "(间推)!");
            surplus = surplus.subtract(temAmount);
        }
        //查找上游v1,v2,v3
        String v1 = null, v2 = null, v3 = null;
        if (listMemberMap.size() >= 2) {
            int count = listMemberMap.size();
            for (int i = 1; i < listMemberMap.size(); i++) {
                if (Integer.valueOf(listMemberMap.get(i).get("memberUserLevel")) == 3) {
                    v3 = listMemberMap.get(i).get("memberUserId");
                    count = i;
                    break;
                }
            }
            for (int i = 1; i < count; i++) {
                if (Integer.valueOf(listMemberMap.get(i).get("memberUserLevel")) == 2) {
                    v2 = listMemberMap.get(i).get("memberUserId");
                    count = i;
                    break;
                }
            }
            for (int i = 1; i < count; i++) {
                if (Integer.valueOf(listMemberMap.get(i).get("memberUserLevel")) == 1) {
                    v1 = listMemberMap.get(i).get("memberUserId");
                    break;
                }
            }
        }
        //（v1+v2+v3）分红占比，最高不超过30%
        BigDecimal bonus = new BigDecimal(0.3);
        if (StringUtils.isNotEmpty(v1)) {
            if (StringUtils.isNotEmpty(v2)) {
                if (StringUtils.isNotEmpty(v3)) {
                    //v1 不空，v2不空 ，v3不空
                    temAmount = amount.multiply(new BigDecimal(0.08));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v1, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v1, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    temAmount = amount.multiply(new BigDecimal(0.08));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v2, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v2, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    temAmount = amount.multiply(new BigDecimal(0.14));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v3, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v3, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                } else {
                    //v1 不空，v2 不空 ，v3空
                    temAmount = amount.multiply(new BigDecimal(0.08));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v1, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v1, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    temAmount = amount.multiply(new BigDecimal(0.08));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v2, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v2, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    bonus = new BigDecimal(0.16);
                }
            } else {
                if (StringUtils.isNotEmpty(v3)) {
                    //v1 不空，v2 空 ，v3不空
                    temAmount = amount.multiply(new BigDecimal(0.08));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v1, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v1, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    temAmount = amount.multiply(new BigDecimal(0.22));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v3, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v3, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                } else {
                    //v1 不空，v2 空 ，v3空
                    temAmount = amount.multiply(new BigDecimal(0.08));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v1, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v1, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    bonus = new BigDecimal(0.08);
                }
            }
        } else {
            if (StringUtils.isNotEmpty(v2)) {
                if (StringUtils.isNotEmpty(v3)) {
                    //v1 空，v2 不空 ，v3不空
                    temAmount = amount.multiply(new BigDecimal(0.16));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v2, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v2, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    temAmount = amount.multiply(new BigDecimal(0.14));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v3, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v3, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                } else {
                    //v1 空，v2 不空 ，v3空
                    temAmount = amount.multiply(new BigDecimal(0.16));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v2, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v2, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                    bonus = new BigDecimal(0.16);
                }
            } else {
                //v1 空，v2 空 ，v3不空
                if (StringUtils.isNotEmpty(v3)) {
                    temAmount = amount.multiply(new BigDecimal(0.3));
                    userBaseMapperExt.systemRechargeAddUserWalletInfo(v3, CoinTypeEnum.USDT.getCode(), temAmount);
                    insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, v3, null, new Date(),
                            CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note);
                }
            }
        }
        temAmount = amount.multiply(bonus);
        surplus = surplus.subtract(temAmount);
        temAmount = amount.multiply(new BigDecimal(0.15));
        //获取用户社区顶级用户ID
        String appUserId = listMemberMap.get(listMemberMap.size() - 1).get("memberUserId");

        userBaseMapperExt.addTeamBonusPool(appUserId, CoinTypeEnum.USDT.getCode(), temAmount);
        surplus = surplus.subtract(temAmount);
        BackTeamBonusPoolFlowDTO backTeamBonusPoolFlowDTO = new BackTeamBonusPoolFlowDTO();
        backTeamBonusPoolFlowDTO.setFlowOrderId(OrderNoGenerate.getOrderIdByTime());
        backTeamBonusPoolFlowDTO.setTeamUserId(appUserId);
        backTeamBonusPoolFlowDTO.setFromUserId(buyPointCardReqDTO.getUserId());
        backTeamBonusPoolFlowDTO.setType(1);
        backTeamBonusPoolFlowDTO.setCoin(CoinTypeEnum.USDT.getCode());
        backTeamBonusPoolFlowDTO.setAmount(temAmount);
        userBaseMapperExt.addBackTeamBonusPoolFlow(backTeamBonusPoolFlowDTO);

        // 添加到该用户团队分红奖金池
        String adminAppUserId = userBaseMapperExt.findAppUserIdByUserName("admin");

        String bacaUserId = userBaseMapperExt.findBackUserIdByAppUserId(appUserId);

        if (StringUtils.isEmpty(bacaUserId) || adminAppUserId.equals(appUserId)) {
            //社区一级用户不关联独立后台用户,分红剩余归总后台
            userBaseMapperExt.systemRechargeAddUserWalletInfo(adminAppUserId, CoinTypeEnum.USDT.getCode(), surplus);
            insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, adminAppUserId, null, new Date(),
                    CoinTypeEnum.USDT.getCode(), surplus, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note + "(总后台分红)!");
        } else {
            //社区一级用户关联独立后台用户,
            // 总后台拿对应分红占比
            temAmount = amount.multiply(userBaseMapperExt.findAdminRatioByBackUserId(bacaUserId));
            userBaseMapperExt.systemRechargeAddUserWalletInfo(adminAppUserId, CoinTypeEnum.USDT.getCode(), temAmount);
            insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, adminAppUserId, null, new Date(),
                    CoinTypeEnum.USDT.getCode(), temAmount, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note + "(合伙人分红)!");

            //分红剩余归独立总后台
            surplus = surplus.subtract(temAmount);
            userBaseMapperExt.systemRechargeAddUserWalletInfo(appUserId, CoinTypeEnum.USDT.getCode(), surplus);
            insertWalletAssetsFlow(OrderNoGenerate.getOrderIdByTime(), buyPointCardReqDTO.getUserId(), null, appUserId, null, new Date(),
                    CoinTypeEnum.USDT.getCode(), surplus, WalletAssetsFlowTypeEnum.INTRODUCE.getCode(), null, note + "(合伙人分红剩余部分)!");
        }
    }

    private int insertWalletAssetsFlow(String flowOrderId, String userId, String fromAddress, String toUserId, String toAddress, Date createTime, String coin,
                                       BigDecimal amount, Integer type, String txHash, String note) {
        WalletAssetsFlow walletAssetsFlow = new WalletAssetsFlow();
        walletAssetsFlow.setFlowOrderId(flowOrderId);
        walletAssetsFlow.setUserId(userId);
        walletAssetsFlow.setFromAddress(fromAddress);
        walletAssetsFlow.setToUserId(toUserId);
        walletAssetsFlow.setToAddress(toAddress);
        walletAssetsFlow.setCreateTime(createTime);
        walletAssetsFlow.setCoin(coin);
        walletAssetsFlow.setAmount(amount);
        walletAssetsFlow.setType(type);
        walletAssetsFlow.setTxHash(txHash);
        walletAssetsFlow.setNote(note);
        int i = walletAssetsFlowMapperExt.insertSelective(walletAssetsFlow);
        return i;
    }

}
